package com.commons.utils;

import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import net.dreamlu.mica.ip2region.core.Ip2regionSearcher;
import net.dreamlu.mica.ip2region.core.IpInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.UnknownHostException;
import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;

public class StringUtils extends org.apache.commons.lang3.StringUtils {

    private final static Logger LOGGER=LoggerFactory.getLogger(StringUtils.class);

    private static final char SEPARATOR = '_';
    private static final String UNKNOWN = "unknown";


    /**
     * 注入bean
     */
    private final static Ip2regionSearcher IP_SEARCHER=SpringContextHolder.getBean(Ip2regionSearcher.class);

    /**
     * 驼峰命名法工具
     *
     * @return toCamelCase(" hello_world ") == "helloWorld"
     * toCapitalizeCamelCase("hello_world") == "HelloWorld"
     * toUnderScoreCase("helloWorld") = "hello_world"
     */
    public static String toCamelCase(String s){
        if(s==null){
            return null;
        }
        s=s.toLowerCase();

        StringBuilder sb=new StringBuilder(s.length());
        boolean upperCase=false;
        for(int i=0;i<s.length();i++){
            char c=s.charAt(i);
            if(c==SEPARATOR){
                upperCase=true;
            }else if(upperCase){
                sb.append(Character.toUpperCase(c));
                upperCase=false;
            }else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /**
     * 驼峰命名法工具
     *
     * @return toCamelCase(" hello_world ") == "helloWorld"
     * toCapitalizeCamelCase("hello_world") == "HelloWorld"
     * toUnderScoreCase("helloWorld") = "hello_world"
     */
    public static String toCapitalizeCamelCase(String s){
        if(s==null){
            return null;
        }
        s=toCamelCase(s);
        return s.substring(0,1).toUpperCase()+s.substring(1);
    }

    /**
     * 驼峰命名法工具
     *
     * @return toCamelCase(" hello_world ") == "helloWorld"
     * toCapitalizeCamelCase("hello_world") == "HelloWorld"
     * toUnderScoreCase("helloWorld") = "hello_world"
     */
    public static String toUnderScoreCase(String s){
        if(s==null){
            return null;
        }
        StringBuilder sb=new StringBuilder();
        boolean upperCase = false;
        for(int i=0;i<s.length();i++){
            char c=s.charAt(i);
            boolean nextUpperCase=true;
            if(i<(s.length()-1)){
                nextUpperCase=Character.isUpperCase(s.charAt(i+1));
            }
            if((i>0)&&Character.isUpperCase(c)){
                if(!upperCase||!nextUpperCase){
                    sb.append(SEPARATOR);
                }
                upperCase=true;
            }else {
                upperCase=false;
            }
            sb.append(Character.toLowerCase(c));
        }
        return sb.toString();
    }

    /**
     * 获取ip地址
     */
    public static String getIp(HttpServletRequest request) {
        String ip=request.getHeader("x-forwarded-for");
        if(ip==null||ip.length()==0||UNKNOWN.equalsIgnoreCase(ip)){
            ip=request.getHeader("Proxy-Client-IP");
        }
        else {
            ip=request.getRemoteAddr();
        }
        String comma=",";
        String localhost="127.0.0.1";
        if(ip.contains(comma)){
            ip=ip.split(",")[0];
        }
        if(localhost.equals(ip)){
            try {
                ip=InetAddress.getLocalHost().getHostAddress();
            }catch (UnknownHostException e){
                LOGGER.error(e.getMessage(),e);
            }

        }
        return ip;
    }

    /**
     * 根据ip获取详细地址
     */
    public static String getCityInfo(String ip) {
        IpInfo ipInfo = IP_SEARCHER.memorySearch(ip);
        if(ipInfo != null){
            return ipInfo.getAddress();
        }
        return null;
    }

    public static String getBrowser(HttpServletRequest request) {
        UserAgent ua = UserAgentUtil.parse(request.getHeader("User-Agent"));
        String browser = ua.getBrowser().toString() + " " + ua.getVersion();
        return browser.replace(".0.0.0","");
    }

    /**
     * 获得当天是周几
     */
    public static String getWeekDay() {
        String[] weekDays = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());

        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0) {
            w = 0;
        }
        return weekDays[w];
    }

    /**
     * 获取当前机器的IP
     *
     * @return /
     */
    public static String getLocalIp() {
        try {
            InetAddress candidateAddress = null;
            // 遍历所有的网络接口
            for (Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces(); interfaces.hasMoreElements();) {
                NetworkInterface anInterface = interfaces.nextElement();
                // 在所有的接口下再遍历IP
                for (Enumeration<InetAddress> inetAddresses = anInterface.getInetAddresses(); inetAddresses.hasMoreElements();) {
                    InetAddress inetAddr = inetAddresses.nextElement();
                    // 排除loopback类型地址
                    if (!inetAddr.isLoopbackAddress()) {
                        if (inetAddr.isSiteLocalAddress()) {
                            // 如果是site-local地址，就是它了
                            return inetAddr.getHostAddress();
                        } else if (candidateAddress == null) {
                            // site-local类型的地址未被发现，先记录候选地址
                            candidateAddress = inetAddr;
                        }
                    }
                }
            }
            if (candidateAddress != null) {
                return candidateAddress.getHostAddress();
            }
            // 如果没有发现 non-loopback地址.只能用最次选的方案
            InetAddress jdkSuppliedAddress = InetAddress.getLocalHost();
            if (jdkSuppliedAddress == null) {
                return "";
            }
            return jdkSuppliedAddress.getHostAddress();
        } catch (Exception e) {
            return "";
        }
    }

}
